package jmm;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;


public class CASDemo {
    static AtomicReference<Integer> reference = new AtomicReference<>(100);
    static AtomicStampedReference<Integer> ref = new AtomicStampedReference<>(100, 1);

    // 特别注意AtomicReference<Integer>中当值超出-128~127会产生新对象
    // 所以之前更改失败
    public static void main(String[] args) {
        System.out.println("============= ABA问题产生 ====================");
        new Thread(() -> {
            System.out.println(reference.compareAndSet(100, 101));
            System.out.println(reference.get() + "\t" + reference.compareAndSet(101, 100));
        }).start();

        new Thread(() -> {
            try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println(reference.compareAndSet(100, 111) + "\t" + reference.get());
        }).start();



        try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("============= ABA问题解决 ================");



        new Thread(() -> {
            int stamp = ref.getStamp();
            System.out.println(ref.compareAndSet(100, 101, ref.getStamp(), ref.getStamp() + 1) + "\t" + ref.getStamp());

            System.out.println(ref.compareAndSet(101, 100, ref.getStamp(), ref.getStamp() + 1) + "\t" + ref.getStamp());
        }).start();

        System.out.println("");

        int stamp = ref.getStamp();
        new Thread(() -> {
            System.out.println("获取版本号\t" + stamp);
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println(ref.compareAndSet(100, 111, stamp, stamp + 1) + "\t" + ref.getStamp());
        }).start();
    }
}
